home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue48 / Memory / APIProg.dpr < prev    next >
Encoding:
Text File  |  1999-06-23  |  7.5 KB  |  276 lines

  1. program APIProg;
  2.  
  3. {$ifdef Ver90} { Delphi 2.0x }
  4.   {$define DelphiLessThan3}
  5.   {$define DelphiLessThan4}
  6. {$endif}
  7. {$ifdef Ver93} { C++ Builder 1.0x }
  8.   {$define DelphiLessThan3}
  9.   {$define DelphiLessThan4}
  10. {$endif}
  11. {$ifdef Ver100} { Delphi 3.0x }
  12.   {$define DelphiLessThan4}
  13. {$endif}
  14.  
  15. {$ifdef Windows}
  16.   'Win32 application only'
  17. {$endif}
  18.  
  19. //Link in custom resources. Note the difference between the
  20. //resource file name and the project name. If you make them the
  21. //same, Delphi will overwrite the RES file with its own one.
  22. {$R API_Prog.Res}
  23.  
  24. uses
  25.   Windows, Messages;
  26.  
  27. const
  28.   idm_About = 100;
  29.   idm_Test = 101;
  30.   id_Flash = 57;
  31.  
  32. function Gasp(Wnd: HWnd): Boolean;
  33. var
  34.   Msg: TMsg;
  35. begin
  36.   Result := True;
  37.   { While we have messages to process, process them }
  38.   while PeekMessage(Msg, 0, 0, 0, pm_Remove) do
  39.   begin
  40.     { Except Quit, of course }
  41.     if Msg.Message = wm_Quit then
  42.     begin
  43.       { In which case post another quit message for }
  44.       { the main message loop to catch, and thus exit }
  45.       PostQuitMessage(Msg.WParam);
  46.       { Return False so caller can break out of processing loop }
  47.       Result := False;
  48.       { Bail out }
  49.       Break;
  50.     end;
  51.     { Translate virtual key messages into character messages }
  52.     TranslateMessage(Msg);
  53.     { Send message to relevant window }
  54.     DispatchMessage(Msg);
  55.   end;
  56. end;
  57.  
  58. function CommittedMemorySize: DWord;
  59. var
  60.   MBI: TMemoryBasicInformation;
  61.   SI: TSystemInfo;
  62.   RangeStart: Pointer;
  63. begin
  64.   Result := 0;
  65.   GetSystemInfo(SI);
  66.   RangeStart := SI.lpMinimumApplicationAddress;
  67.   while DWord(RangeStart) < DWord(SI.lpMaximumApplicationAddress) do
  68.   begin
  69.     VirtualQuery(RangeStart, MBI, SizeOf(MBI));
  70.     //Only get committed memory (storage allocated for this)
  71.     if MBI.State = MEM_COMMIT then
  72.       Inc(Result, MBI.RegionSize);
  73.     //Delphi 2 & 3 could only handle $7FFFFFFF as biggest int
  74.     //Last region is likely to end at $80000000. To avoid integer
  75.     //overflow, we'll do a comparison and bypass the addition
  76.     if DWord(SI.lpMaximumApplicationAddress)-MBI.RegionSize >= DWord(RangeStart) then
  77.       Inc(PChar(RangeStart), MBI.RegionSize)
  78.     else
  79.       //If overflow would have occurred, loop is over
  80.       Break
  81.   end;
  82. end;
  83.  
  84. function About(Dialog: HWnd; Msg, WParam: Word;
  85.   LParam: Longint): Bool; {$ifdef Win32}stdcall{$else}export{$endif};
  86. var
  87.   Loop: Word;
  88. begin
  89.   About := True;
  90.   case Msg of
  91.     wm_InitDialog:
  92.       Exit;
  93.     wm_Command:
  94.       case WParam of
  95.         id_Ok, id_Cancel:
  96.           begin
  97.             EndDialog(Dialog, WParam);
  98.             Exit;
  99.           end;
  100.         id_Flash:
  101.           begin
  102.             for Loop := 1 to 5000 do
  103.             begin
  104.               { EndDialog hides the window, but doesn't destroy it }
  105.               { until the dialog procedure finishes. When asked to }
  106.               { close we ought to stop doing our stuff }
  107.               if not IsWindowVisible(Dialog) then
  108.                 Break;
  109.               FlashWindow(Dialog, True);
  110.               Gasp(Dialog);
  111.             end;
  112.             Exit;
  113.           end;
  114.       end;
  115.   end;
  116.   About := False;
  117. end;
  118.  
  119. function WindowProc(Window: HWnd; Msg, WParam: Word;
  120.   LParam: Longint): Longint; {$ifdef Win32}stdcall{$else}export{$endif};
  121. var
  122.   AboutProc: TFarProc;
  123.   Loop: Longint;
  124.   DC: HDC;
  125.   Rect: TRect;
  126.   OldPen: HPen;
  127.   CaptionStr: String;
  128. begin
  129.   WindowProc := 0;
  130.   case Msg of
  131.     wm_Command:
  132.       case WParam of
  133.         idm_About:
  134.           begin
  135.             AboutProc := MakeProcInstance(@About, HInstance);
  136.             DialogBox(HInstance, 'AboutBox', Window, AboutProc);
  137.             FreeProcInstance(AboutProc);
  138.             Exit;
  139.           end;
  140.         idm_Test:
  141.           begin
  142.             for Loop := 1 to 1000 do
  143.             begin
  144.               if not Gasp(Window) then
  145.                 Break;
  146.               GetClientRect(Window, Rect);
  147.               DC := GetDC(Window);
  148.               OldPen := SelectObject(DC, CreatePen(ps_Solid, Random(11),
  149.                 RGB(Random(256), Random(256), Random(256))));
  150.               MoveToEx(DC, Random(Rect.Right), Random(Rect.Bottom), nil);
  151.               LineTo(DC, Random(Rect.Right), Random(Rect.Bottom));
  152.               DeleteObject(SelectObject(DC, OldPen));
  153.               ReleaseDC(Window, DC);
  154.             end;
  155.             Exit;
  156.           end;
  157.       end;
  158.     wm_Timer:
  159.       begin
  160.         Str(CommittedMemorySize div 1024, CaptionStr);
  161.         CaptionStr := CaptionStr + ' kilobytes';
  162.         SetWindowText(Window, PChar(CaptionStr))
  163.       end;
  164.     wm_Destroy:
  165.       begin
  166.         PostQuitMessage(0);
  167.         Exit;
  168.       end;
  169.   end;
  170.   WindowProc := DefWindowProc(Window, Msg, WParam, LParam);
  171. end;
  172.  
  173. procedure WinMain;
  174. var
  175.   Window: HWnd;
  176.   Msg: TMsg;
  177.   AccelTbl: THandle;
  178. const
  179.   AppName = 'Generic';
  180.   WindowClass: TWndClass = (
  181.     style: 0;
  182.     lpfnWndProc: @WindowProc;
  183.     cbClsExtra: 0;
  184.     cbWndExtra: 0;
  185.     hInstance: 0;
  186.     hIcon: 0;
  187.     hCursor: 0;
  188.     hbrBackground: 0;
  189.     lpszMenuName: AppName;
  190.     lpszClassName: AppName);
  191. begin
  192.   if HPrevInst = 0 then
  193.   begin
  194.     WindowClass.hInstance := HInstance;
  195.     WindowClass.hIcon := LoadIcon(0, idi_Application);
  196.     WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  197.     WindowClass.hbrBackground := GetStockObject(white_Brush);
  198.     if not Bool(RegisterClass(WindowClass)) then
  199.       Halt(255);
  200.   end;
  201.   AccelTbl := LoadAccelerators(HInstance, AppName);
  202.   Window := CreateWindow(
  203.     AppName,
  204.     nil,
  205.     ws_OverlappedWindow,
  206.     Integer(cw_UseDefault),
  207.     Integer(cw_UseDefault),
  208.     Integer(cw_UseDefault),
  209.     Integer(cw_UseDefault),
  210.     0,
  211.     0,
  212.     HInstance,
  213.     nil);
  214.   SetTimer(Window, 1, 100, nil);
  215.   ShowWindow(Window, CmdShow);
  216.   UpdateWindow(Window);
  217.   while GetMessage(Msg, 0, 0, 0) do
  218.     if TranslateAccelerator(Window, AccelTbl, Msg) = 0 then
  219.     begin
  220.       TranslateMessage(Msg);
  221.       DispatchMessage(Msg);
  222.     end;
  223.   Halt(Msg.wParam);
  224. end;
  225.  
  226. (* // Windows 95/98 version
  227. procedure RemoveExcessDLLs;
  228. begin
  229.   //Stop the RTL wanting to clear System Variants
  230. {$ifndef DelphiLessThan4}
  231.   TVarData(EmptyParam).VType := varEmpty;
  232. {$endif}
  233.   //These two seem to be considered constants, so we hack around
  234.   //this by de-referencing the "constant" item's address
  235.   TVarData((@Null)^).VType := varEmpty;
  236.   TVarData((@Unassigned)^).VType := varEmpty;
  237.   //Unload OLEAUT32.DLL, which will in turn unload OLE32.DLL
  238.   FreeLibrary(GetModuleHandle('OLEAUT32.DLL'));
  239. end; *)
  240.  
  241. // Windows NT version
  242. procedure ReduceMemoryOverhead;
  243. var
  244.   ProcessHandle: THandle;
  245.   OSVersionInfo: TOSVersionInfo;
  246. begin
  247.   //Stop the RTL wanting to clear System Variants
  248. {$ifndef DelphiLessThan4}
  249.   TVarData(EmptyParam).VType := varEmpty;
  250. {$endif}
  251.   //These two seem to be considered constants, so we hack around
  252.   //this by de-referencing the "constant" item's address
  253.   TVarData((@Null)^).VType := varEmpty;
  254.   TVarData((@Unassigned)^).VType := varEmpty;
  255.   //Unload OLEAUT32.DLL, which will in turn unload OLE32.DLL
  256.   FreeLibrary(GetModuleHandle('OLEAUT32.DLL'));
  257.  
  258.   OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);
  259.   if GetVersionEx(OSVersionInfo) and (OSVersionInfo.dwPlatformID = VER_PLATFORM_WIN32_NT) then
  260.   begin
  261.     ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, GetCurrentProcessID);
  262.     //Remove any unimportant code/data from memory
  263.     SetProcessWorkingSetSize(ProcessHandle, -1, -1);
  264.     CloseHandle(ProcessHandle);
  265.   end
  266. end;
  267.  
  268. begin
  269. {$ifndef DelphiLessThan3}
  270.   if ParamCount > 0 then
  271.     ReduceMemoryOverhead;
  272. {$endif}
  273.   Randomize;
  274.   WinMain;
  275. end.
  276.